#include <Windows.h>
#include <stdio.h>

/*
		VER 0.1
*/
BOOL parseDLL();
PCHAR getDLL();

int main()
{
	HANDLE hFile = NULL;
	HANDLE hMap  = NULL;
	LPVOID lpFile= NULL;
	PCHAR  pPath = NULL;
	//test
	HMODULE hTest = NULL;
	//test
	printf("DLL export logger (ver: 0.1):\n\nDOES WORK: Kernel32.dll , most un-system DLL's .\nDOES-NOT-WORK: most system DLL's (advapi32,user32,ntdll,...)\nReason being checked.\n\n");
	system("pause");
	system("cls");
	printf("DLL's located in dll_list.txt ,you may add/remove to the file freely.\nIf the file is not presented it will be created\nand you will be asked to input a valid path to a DLL.\n\n");
	pPath = getDLL();
	
	while(pPath == NULL)
	{
		system("cls");
		printf("\nInvalid .dll file, try again.\n");
		pPath = getDLL();
	}//if

	pPath[strlen(pPath)-1] != 'l' ? pPath[strlen(pPath)-1] = '\0' : 0;

	CopyFile(pPath,
			"dummy.dll",
			FALSE);

	pPath = "dummy.dll";

	//test
	hTest = LoadLibrary(pPath);
	//test
	hFile = CreateFile(pPath,
					GENERIC_READ,
					0,
					NULL,
					OPEN_EXISTING,
					0,
					NULL);

	hMap = CreateFileMapping(hFile,
					NULL,
					PAGE_READONLY,
					0,
					0,
					"mapMyDLL");

	lpFile = MapViewOfFile(hMap,
					FILE_MAP_READ,
					0,
					0,
					0);

	parseDLL((LPBYTE)lpFile);
	UnmapViewOfFile(lpFile);
	CloseHandle(hMap);
	CloseHandle(hFile);
	printf("Logged successfully (in log.txt)\n");
	system("pause");
	return 0;
}//main

BOOL parseDLL(LPBYTE lpFile)
{
	INT    offset		 = 0;
	INT    numOfNames    = 0;
	WORD   numOfSections = 0;
	DWORD  timeStamp	 = 0;	
	DWORD  dwNOBW		 = 0;
	HANDLE hFile		 = INVALID_HANDLE_VALUE;
	PCHAR   newLine		 = "\n";

	hFile = CreateFile("log.txt",		//Create log.txt
					GENERIC_WRITE,
					0,
					NULL,
					OPEN_ALWAYS,
					0,
					NULL);

	*(LPWORD)(lpFile) == 0x5A4D ? printf("MZ - checked\n") : printf("Not MZ\n");
	offset += *(LPDWORD)(lpFile+0x3C);	//lpFile+0x3C holds the offset to the PE header.
	*(LPWORD)(lpFile+offset) == 0x4550 ? printf("PE - checked\n") : printf("Not PE\n");
	offset += sizeof(DWORD) + sizeof(WORD);	//number of sections
	numOfSections = *(LPWORD)(lpFile+offset);
	offset += sizeof(WORD);				//time date stamp
	timeStamp = *(LPDWORD)(lpFile+offset);
	offset += sizeof(DWORD);			//pointer2symbolTable
	offset += sizeof(DWORD);			//NumberofSymbols
	offset += sizeof(DWORD);			//sizeofoptionalheaders
	offset += sizeof(WORD) ;			//charecaristics
	offset += sizeof(WORD) ;			//image_optional_headers
	offset += 96;						//image directory entry export
	offset = *(LPDWORD)(lpFile+offset);	//image export directory
	offset += sizeof(DWORD)*6;			//num of names
	numOfNames = *(LPDWORD)(lpFile+offset);
	offset += sizeof(DWORD)*2;			//address_of_names
	offset = *(LPDWORD)(lpFile+offset); //address_of_name_0
	offset = *(LPDWORD)(lpFile+offset); //name_0
	while(numOfNames != 0)				//go through all the names
	{
		WriteFile(hFile,				//Name of function
				(lpFile+offset),
				strlen((PCHAR)(lpFile+offset)),
				&dwNOBW,
				NULL);

		WriteFile(hFile,				//New line
				newLine,
				strlen(newLine),
				&dwNOBW,
				NULL);

		offset += strlen((PCHAR)(lpFile+offset)) + 1;	//Update offset (current + the length of the string + 1 byte that is the end-of-string symbol)
		numOfNames --;									//One less names to go through
	}
	CloseHandle(hFile);					//close handle
	return TRUE;
}//parseDLL

/*
	This function reads from a file which lists dll's
*/
PCHAR getDLL()
{
	HANDLE hFile     = INVALID_HANDLE_VALUE;
	HANDLE hMap      = INVALID_HANDLE_VALUE;
	LPVOID lpFile    = NULL;
	PCHAR  pPath     = NULL;
	CHAR   choice    = '\0';
	DWORD  dwNOBW    = 0;
	INT    offset    = 0;
	INT    subOffset = 0;
	INT    counter   = 1;

	hFile = CreateFile("dll_list.txt",
					GENERIC_READ,
					0,
					NULL,
					OPEN_ALWAYS,
					0,
					NULL);

	pPath = (PCHAR) calloc(151,sizeof(BYTE));

	if(GetFileSize(hFile,NULL) == 0)	//if file is empty - enter a .dll path
	{
		CloseHandle(hFile);
		hFile = CreateFile("dll_list.txt",
					FILE_APPEND_DATA,
					0,
					NULL,
					OPEN_ALWAYS,
					0,
					NULL);
		printf("Enter a .dll path:\t");
		scanf("%s",pPath);
		if(pPath[strlen(pPath)] == 'l')
			if(strcmp(pPath+strlen(pPath)-3 , ".dll") == 0)
			{
				WriteFile(hFile,
				pPath,
				strlen(pPath),
				&dwNOBW,
				NULL);
				CloseHandle(hFile);
				return pPath;
			}//if
		if(pPath[strlen(pPath)] != 'l')
			if(strcmp(pPath+strlen(pPath)-4 , ".dll") == 0)
			{
				WriteFile(hFile,
						pPath,
						strlen(pPath),
						&dwNOBW,
						NULL);
				CloseHandle(hFile);
				return pPath;
			}//if
		CloseHandle(hFile);
		return NULL;
	}//if

	hMap = CreateFileMapping(hFile,
					NULL,
					PAGE_READONLY,
					0,
					0,
					NULL);

	lpFile = MapViewOfFile(hMap,
					FILE_MAP_READ,
					0,
					0,
					0);
	
	printf("Please choose a DLL from the following:\n\n");
	printf("[%d] ",counter);
	while(offset != GetFileSize(hFile,NULL))
	{
		printf("%c",*((PCHAR)lpFile+offset));
		if (*((PCHAR)lpFile+offset) == '\n')
		{
			counter++;
			printf("[%d] ",counter);
		}//if
		offset += sizeof(BYTE);
	}//while
	printf("\n\nPlease enter your choice (other to open a different dll):\t");
	scanf(" %c",&choice);
	if(atoi(&choice)<1 || atoi(&choice)>counter)
	{
		UnmapViewOfFile(lpFile);
		CloseHandle(hMap);
		CloseHandle(hFile);
		hFile = CreateFile("dll_list.txt",
					FILE_APPEND_DATA,
					0,
					NULL,
					OPEN_ALWAYS,
					0,
					NULL);
		printf("\nEnter a .dll path:\t");
		pPath[0] = '\n';
		scanf("%s",pPath+1);
		if(pPath[strlen(pPath)] == 'l')
			if(strcmp(pPath+strlen(pPath)-3 , ".dll") == 0)
			{
				WriteFile(hFile,
				pPath,
				strlen(pPath),
				&dwNOBW,
				NULL);
				CloseHandle(hFile);
				return pPath;
			}//if
		if(pPath[strlen(pPath)] != 'l')
			if(strcmp(pPath+strlen(pPath)-4 , ".dll") == 0)
			{
				WriteFile(hFile,
						pPath,
						strlen(pPath),
						&dwNOBW,
						NULL);
				CloseHandle(hFile);
				return pPath;
			}//if
		CloseHandle(hFile);
		return NULL;
	}//if
	
	offset = 0;
	counter= 1;
	if(atoi(&choice) != 1)
		while(counter != atoi(&choice))
		{
			if (*((PCHAR)lpFile+offset) == '\n')
				counter++;
			offset += sizeof(BYTE);
		}//while
	while(*((PCHAR)lpFile+offset) != '\n' && *((PCHAR)lpFile+offset) != '\0' && *((PCHAR)lpFile+offset) != EOF)
	{
		*(pPath+subOffset) = *((PCHAR)lpFile+offset);
		subOffset++;
		offset++;
	}//while
	*(pPath+subOffset+1) = '\0';
	printf("\n%s\n",pPath);
	CloseHandle(hFile);
	if(pPath[strlen(pPath)] == 'l')
		if(strcmp(pPath+strlen(pPath)-3 , ".dll") == 0)
			return pPath;
	if(pPath[strlen(pPath)] != 'l')
		if(strcmp(pPath+strlen(pPath)-4 , ".dll") == 0)
			return pPath;
	return NULL;
}//listofDLLs